﻿using System;
using System.IO;
using System.Xml;
using System.Xml.Schema;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Peter.Tests
{
   [TestClass]
   public class AvalonEditHighlightingTests
   {
      private string m_Errors = string.Empty;
      private string m_Warnings = string.Empty;

      /// <summary>
      /// Gets or Sets the text context.
      /// </summary>
      public TestContext TestContext { get; set; }

      /// <summary>
      /// Tests all highlighting files against avalon edit schema.
      /// </summary>
      [TestMethod]
      public void AvalonEditHighlightingFilesTest ()
      {
         var highlightingDir = this.TestContext.TestDir;
         highlightingDir = highlightingDir.Substring (0, highlightingDir.LastIndexOf ('\\'));
         highlightingDir = highlightingDir.Substring (0, highlightingDir.LastIndexOf ('\\'));
         highlightingDir += "\\Peter\\AvalonEdit.Highlighting\\";
         var schema = highlightingDir + "ModeV2.xsd";
         var files = Directory.GetFiles (highlightingDir, "*.xshd");
         foreach (var file in files) {
            this.TestHighlightingFile (schema, file);
         }
         if (!string.IsNullOrWhiteSpace (this.m_Warnings))
            Console.Write (this.m_Warnings);
         if (!string.IsNullOrWhiteSpace (this.m_Errors))
            Assert.Fail (this.m_Errors);
         if (!string.IsNullOrWhiteSpace (this.m_Warnings))
            Assert.Inconclusive ("Warings found in avalon edit highlighting. See output for details.");
      }

      /// <summary>
      /// Tests a given highlighting file against the schema.
      /// </summary>
      /// <param name="schema">The highlighting schema</param>
      /// <param name="file">The highlighting file to test.</param>
      public void TestHighlightingFile (string schema, string file)
      {
         // Set the validation settings.
         var settings = new XmlReaderSettings { ValidationType = ValidationType.Schema };
         settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
         settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
         settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
         settings.ValidationEventHandler += this.ValidationCallBack;
         settings.Schemas.Add (null, schema);
         // Create the XmlReader object.
         var reader = XmlReader.Create (file, settings);
         // Parse the file.
         while (reader.Read ()) {}
      }

      /// <summary>
      /// Display any schema validation warnings or errors.
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="args">ValidationEventArgs</param>
      private void ValidationCallBack (object sender, ValidationEventArgs args)
      {
         var reader = sender as XmlReader;
         var file = reader == null ? string.Empty : reader.BaseURI + " - ";
         if (args.Severity == XmlSeverityType.Warning)
            this.m_Warnings += file + args.Message + Environment.NewLine;
         else
            this.m_Errors += file + args.Message + Environment.NewLine;
      }
   }
}
